/***************************************************************************
 *   Copyright (C) 2006 by Matej Svejda                                    *
 *   mata@aw-modell.at                                                     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "metronome.h"
#include "metronome.moc"

Metronome::Metronome(QWidget *parent, const char *name) :
	QWidget(parent, name)
{
	beat = 0;
	noteCount = 0;
	currentBeat = -1;
	accent = -1;
	
	setMinimumHeight(50);
	setMinimumWidth(200);
	setMaximumHeight(50);
	setMaximumWidth(200);
	
	setBackgroundColor(Qt::white);

	beatInstances[Beat::Beep] = new BeepBeat(this);
	beatInstances[Beat::Click] = new SDLBeat("click", "", this);
	beatInstances[Beat::Knock] = new SDLBeat("knock", "", this);
	
	connect(this, SIGNAL(volumeChanged(float)), beatInstances[Beat::Beep], SLOT(setVolume(float)));
	connect(this, SIGNAL(volumeChanged(float)), beatInstances[Beat::Click], SLOT(setVolume(float)));
	connect(this, SIGNAL(volumeChanged(float)), beatInstances[Beat::Knock], SLOT(setVolume(float)));
		
	visualization = new SinusVisualization(this, QRect(10, 10, width() - 20, height() -20), this);
	
	contextMenu = new QPopupMenu(this);
	contextMenu->insertItem(i18n("Hide"), this, SLOT(hideVisualization()));
	
	KContextMenuManager::insert(this, contextMenu);
}


Metronome::~Metronome()
{
}

void Metronome::timeout()
{
	//qDebug("Timout");
	if(accent != -1 && noteCount % accent == 0) {
		//qDebug("Making accentuated sound");
		beat->makeAccentuatedSound();
		visualization->nextBeat(Visualization::Accentuated);
	} else {
		//qDebug("Making normal sound");
		beat->makeSound();
		visualization->nextBeat(Visualization::Normal);
	}
	noteCount++;
	if((accent != -1 && noteCount > accent) || (accent == -1 && noteCount > 4)) {
		noteCount = 1;
	}
}

void Metronome::setAccent(int accentuated) 
{
	accent = accentuated;
	noteCount = accent;
}

void Metronome::setBPM(int aBPM)
{
	bpm = aBPM;
	visualization->setBPM(aBPM);
	if(timer.isActive()) {
		start();
	}
}

void Metronome::start()
{
	//qDebug("Starting metronome-timer.");
	timer.start(60000 / bpm);
	visualization->start();
}

void Metronome::stop()
{
	timer.stop();
	visualization->stop();
}

void Metronome::setBeat(int type)
{
	//qDebug("Setting beat to: %d", type);

	if(type == currentBeat) {
		return;
	}
	
	timer.disconnect(SIGNAL(timeout()));
	
	beat = beatInstances[type];
	if(!beat->isAvailable()) {
		KMessageBox::error( this, i18n("Couldn't load soundfile. Maybe the soundfiles are missing or the sound-device is being used by another program."));
	}
		
	qWarning("Type changed to type %d.", type);
	currentBeat = type;

	// We need to connet again.
	connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
}

void Metronome::paintEvent(QPaintEvent *)
{
	if(visualization->isVisible()) {
		QPainter painter(this);
		painter.drawRect(0, 0, width(), height());
	}
}

void Metronome::setVisualizationVisibility(bool visible)
{
	if(visible) {
		visualization->setVisibility(true);
		setHidden(false);
		if(timer.isActive()) {
			visualization->start();
		}
	} else {
		visualization->setVisibility(false);
		setHidden(true);
		visualization->stop();
	}
	emit(visualizationVisibilityChanged(visible));
}





